﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using CustomControlDatabaseInterface.Model;
using CustomControlDatabaseInterface.Utilities;

namespace CustomControlDatabaseInterface.ViewModel
{

    public class ViewCustomersViewModel : WorkspaceViewModel
    {
        public FilterableCustomerList AllCustomers { get; set; }
        public ObservableCollection<String> CustomersList { get; set; }

        private List<String> CustomerListFilterBackup { get; set; }

        private List<TechControlFilter> TechControlFilterList { get; set; }  

        public NotifyCollectionChangedEventHandler CustomersListChangedHandler;  

        private String nameFilter;
        public String NameFilter
        {
            get { return nameFilter; }
            set
            {
                nameFilter = value;
                OnPropertyChanged("NameFilter");
                FilterCustomersByName();
            }
        }

        private String customerCount;
        public String CustomerCount
        {
            get { return customerCount; }
            set
            {
                customerCount = value;
                OnPropertyChanged("CustomerCount");
            }
        }

        private String selectedCustomer;
        public String SelectedCustomer {
            get {
                return this.selectedCustomer; 
            }
            set {
                if (value != null) {
                    this.selectedCustomer = value;
                    OnPropertyChanged("SelectedCustomer");
                    OnViewDetails(selectedCustomer);
                }
               
            }
        }
                
        public ViewCustomersViewModel()
        {
            InitializeProperties();

            CustomersListChangedHandler = delegate
            {
                CustomerCount = "Customer Count: " + CustomersList.Count;
            };
            CustomersList.CollectionChanged += CustomersListChangedHandler;
            CustomerCount = "Customer Count: " + CustomersList.Count; 
            
            ShowFilterViewCommand = new RelayCommand(param => OnViewFilter());
        }


        public ICommand ShowFilterViewCommand { get; set; }

        public delegate void ViewFilterEventHandler();

        public event ViewFilterEventHandler RequestViewFilter; 

        public void OnViewFilter() {
            ViewFilterEventHandler handler = this.RequestViewFilter;
            if (RequestViewFilter != null) {
                handler(); 
            }
        }

        public delegate void ViewDetailsEventHandler(String customerName );

        public event ViewDetailsEventHandler ViewDetails; 

        public void OnViewDetails( String customerName ) {
            ViewDetailsEventHandler handler = this.ViewDetails; 
            if (ViewDetails != null) {
                handler(customerName);
            }
        }

        public void OnFilterApplyied(TechControlFilter filter) {
            CustomerListFilterBackup = CustomersList.ToList(); 
            TechControlFilterList.Add(filter);
        }

        public void OnFilterRemoved( TechControlFilter filter ) {
            TechControlFilterList.Remove(filter);
            CustomerListFilterBackup = AllCustomers.List; 
            foreach (TechControlFilter item in TechControlFilterList) {
                UpdateOnCurrentCustomerList(item);
            }
        }

        public void OnAllFiltersRemove() {
            UpdateObservableCollection(CustomersList, AllCustomers.List);
            CustomerListFilterBackup = AllCustomers.List; 
            TechControlFilterList.Clear();
        }

        public void OnTechnologySelected(String technology) {
            UpdateObservableCollection(CustomersList, CustomerListFilterBackup);
            if (CustomersList.Count < 1) {
                ViewModelUtil.UpdateObservableCollection(CustomersList, AllCustomers.FilterByTechnology(technology));
            }
            else {
                UpdateOnCurrentCustomerList(new TechControlFilter(technology, null));
            }
            if (NameFilter != String.Empty) {
                NameFilter = "";
            }
            
        }

        public void OnControlSelected(String technology, String control) {
            UpdateObservableCollection(CustomersList, CustomerListFilterBackup);
            if (CustomersList.Count < 1) {
                ViewModelUtil.UpdateObservableCollection(
                    CustomersList, AllCustomers.FilterByControl(technology, control));
            }
            else {
                UpdateOnCurrentCustomerList(new TechControlFilter(technology, control));
            }
            if (NameFilter != String.Empty) {
                NameFilter = ""; 
            }
        }

        private void FilterCustomersByName()
        {
            CustomersList.Clear();
            ObservableCollection<String> tempList = ViewModelUtil.ConvertToObservableCollection(AllCustomers.FilterbyName(NameFilter));
            foreach(string item in tempList)
            {
                CustomersList.Add(item);
            }
        }

        private void InitializeProperties()
        {
            AllCustomers = new FilterableCustomerList();
            CustomersList = new ObservableCollection<string>();
            CustomerListFilterBackup = new List<string>();
            TechControlFilterList = new List<TechControlFilter>();

            NameFilter = ""; 

            
            UpdateObservableCollection(CustomersList, AllCustomers.GetList());
            CustomerListFilterBackup = AllCustomers.GetList(); 
        }

        private void UpdateOnCurrentCustomerList( TechControlFilter filter ) {
            String query = "USE " + DatabaseUtil.Database + ";";
            query += "SELECT kunde FROM " + filter.Technology + " WHERE ";
            String customerControlConstraint;
            if (filter.Control != null) {
                customerControlConstraint = String.Format("(`kunde`='{0}' AND `{1}`!='')", CustomersList[0], filter.Control);
            }
            else {
                customerControlConstraint = String.Format("(`kunde`='{0}')", CustomersList[0]);
            }
            query += customerControlConstraint; 

            for (int i = 1; i < CustomersList.Count; i++) {
                if (filter.Control != null) {
                    customerControlConstraint = String.Format(
                        " OR (`kunde`='{0}' AND `{1}`!='')", CustomersList[i], filter.Control);
                }
                else {
                    customerControlConstraint = String.Format(" OR `kunde`='{0}'", CustomersList[i]);
                }
                query += customerControlConstraint; 
            }
            query += " ORDER BY kunde;";

            List<String> resultList = DatabaseUtil.GetDataColumn(query, "kunde"); 
            UpdateObservableCollection(CustomersList, resultList);
        }

    }
}
